package com.netease.financial.base.web;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView;

import com.netease.financial.NfsApplication;
import com.netease.financial.base.lockpattern.LockPatternHelper;
import com.netease.financial.base.lockpattern.LockPatternPreferencesHelper;
import com.netease.financial.base.push.PushHelper;
import com.netease.financial.base.share.action.BaseShareAction;
import com.netease.financial.base.share.action.SendToEasyChatFriendAction;
import com.netease.financial.base.share.action.SendToWeChatFriendAction;
import com.netease.financial.base.share.action.ShareOnEasyChatMomentAction;
import com.netease.financial.base.share.action.ShareOnWeChatMomentAction;
import com.netease.financial.base.share.dialog.SharePanelDialog;
import com.netease.financial.base.share.model.ShareHolder;
import com.netease.financial.base.update.ApkDownloadService;
import com.netease.financial.base.web.JSBridge.Command;
import com.netease.financial.common.security.SecurityJNI;
import com.netease.financial.common.util.PackageUtils;
import com.netease.financial.common.util.TelephonyUtils;
import com.netease.financial.common.util.preferences.AppUpdatePreferencesHelper;
import com.netease.financial.navigation.Navigator;

import org.json.JSONObject;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import cn.trinea.android.common.util.JSONUtils;

/**
 * Created by wyf on 7/6/15.
 */
public class JSBridgeHelper {

    private static final String TAG = JSBridgeHelper.class.getSimpleName();

    private final Map<String, JSInterface.WebActionListener> mListenerMap;
    private final Context mContext;
    private final JSBridge mJsBridge;
    private final WebStorageBridge mWebStorageBridge;
    private final WebView mWebView;

    public static JSBridgeHelper newInstance(WebView webView) {
        return new JSBridgeHelper(webView);
    }

    private JSBridgeHelper(WebView webView) {
        mListenerMap = new HashMap<>();
        mContext = webView.getContext();
        mJsBridge = new JSBridge(webView);
        mWebStorageBridge = new WebStorageBridge(webView);
        mWebView = webView;
    }

    public void setCurrentUrl(String url) {
        mJsBridge.setCurrentUrl(url);
    }

    public void addWebActionListener(String request, JSInterface.WebActionListener listener) {
        mListenerMap.put(request, listener);
    }

    public void getLocalStorageItem(String itemName, WebStorageBridge.CallBack callBack) {
        mWebStorageBridge.addLocalStorageItemCallBackListener(itemName, callBack);
    }

    public void saveLocalStorageItem(String itemName, String itemValue) {
        mWebStorageBridge.saveLocalStorageItem(itemName, itemValue);
    }

    public void getSessionStorageItem(String itemName, WebStorageBridge.CallBack callBack) {
        mWebStorageBridge.addSessionStorageItemCallBackListener(itemName, callBack);
    }

    public void saveSessionStorageItem(String itemName, String itemValue) {
        mWebStorageBridge.saveSessionStorageItem(itemName, itemValue);
    }

    public void executeJsFunction(String request, JSONObject params, JSBridge.Callback callback) {
        mJsBridge.execute(request, params, callback);
    }

    private void registerCommand(String commandName, JSBridge.Function function) {
        mJsBridge.registerCommand(commandName, function);
    }

    public void registerCommandForJs() {
        //地理位置信息
        registerCommand(JSInterface.REQUEST_JS_GET_LOCATION, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                SharedPreferences sharedPreferences = mContext.getSharedPreferences("GEOGRAPHY_LOCATION", Activity.MODE_PRIVATE);
                String address = sharedPreferences.getString("SHAREPREFER_LOCATION", "");
                cmd.setResult(address);
            }
        });

        registerCommand(JSInterface.REQUEST_JS_SET_TITLE, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_GET_USER_INFO, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {

            }
        });
        registerCommand(JSInterface.REQUEST_JS_IS_USER_LOGIN, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {

            }
        });
        registerCommand(JSInterface.REQUEST_JS_NAVIGATE_TO_LOGIN_SCREEN, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_LOGOUT, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {

            }
        });
        registerCommand(JSInterface.REQUEST_JS_GET_FORTUNE_CLUB_API_LEVEL, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                cmd.setResult(JSInterface.PARAM_NATIVE_API_LEVEL, JSInterface.JS_INTERFACE_API_LEVEL);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_IS_LOCK_PATTERN_EXISTS, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                String userId = cmd.getParams().optString(JSInterface.PARAM_JS_LOCK_PATTERN_USER_ID);
                cmd.setResult(JSInterface.PARAM_NATIVE_LOCK_PATTERN_EXISTS, LockPatternHelper.isLockPatternExistsForUser(userId));
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SHOW_LOCK_PATTERN_CREATE_SCREEN, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SHOW_LOCK_PATTERN_RESET_SCREEN, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SHARE_ON_WE_CHAT_MOMENT, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                executeShareAction(cmd, new ShareOnWeChatMomentAction());
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SEND_TO_WE_CHAT_FRIEND, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                executeShareAction(cmd, new SendToWeChatFriendAction());
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SHARE_ON_EASY_CHAT_MOMENT, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                executeShareAction(cmd, new ShareOnEasyChatMomentAction());
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SEND_TO_EASY_CHAT_FRIEND, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                executeShareAction(cmd, new SendToEasyChatFriendAction());
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SHOW_SHARE_PANEL, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                SharePanelDialog dialog = new SharePanelDialog(mContext);
                dialog.setShareInfo(ShareHolder.createShareHolderFromJson(cmd.getParams()));
                dialog.setCommand(cmd);
                dialog.show();
            }
        });
        registerCommand(JSInterface.REQUEST_JS_CHOOSE_IMAGE, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_REFRESH_PAGE, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SHOW_OPTION_MENU, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_HIDE_OPTION_MENU, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_ON_MENU_SHARE, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SET_ALIAS_AND_TAGS, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                Set<String> tagSet = new LinkedHashSet<>();
                JSONObject jsonObject = cmd.getParams();

                String alias = jsonObject.optString(JSInterface.PARAM_PUSH_ALIAS, "");
                String[] tags = JSONUtils.getStringArray(jsonObject, JSInterface.PARAM_JS_PUSH_TAGS, null);
                if (tags != null) {
                    tagSet.addAll(Arrays.asList(tags));
                }
                PushHelper.setAliasAndTags(mContext, alias, tagSet);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_RESUME_PUSH, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                PushHelper.resumePush(mContext);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_STOP_PUSH, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                PushHelper.stopPush(mContext);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_GET_VERSION_NAME, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                cmd.setResult(JSInterface.PARAM_NATIVE_APP_VERSION_NAME, PackageUtils.getCurrentApkVersionName(mContext));
            }
        });
        registerCommand(JSInterface.REQUEST_JS_GET_APP_ID, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                cmd.setResult(JSInterface.PARAM_NATIVE_APP_ID, SecurityJNI.getAppId());
            }
        });
        registerCommand(JSInterface.REQUEST_JS_GET_APP_SECRET, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                Bundle bundle = new Bundle();
                bundle.putString(JSInterface.PARAM_NATIVE_APP_SECRET, SecurityJNI.getAppSecret());
                cmd.setResult(bundle);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_GET_VERSION_CODE, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                cmd.setResult(JSInterface.PARAM_NATIVE_APP_VERSION_CODE, PackageUtils.getCurrentApkVersionCode(mContext));
            }
        });
        registerCommand(JSInterface.REQUEST_JS_IS_LOGIN_TIME_OUT, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                cmd.setResult(JSInterface.PARAM_NATIVE_TIME_TIMEOUT, LockPatternPreferencesHelper.isLoginTimeOut());
            }
        });
        registerCommand(JSInterface.REQUEST_JS_PREVIEW_ONLINE_FILE, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                String pdfUrl = cmd.getParams().optString(JSInterface.PARAM_JS_FILE_URL);
                getNavigator().navigateToPreviewOnlinePdf(mContext, pdfUrl);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_UPDATE_APP, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                String apkUrl = cmd.getParams().optString(JSInterface.PARAM_JS_APP_APK_URL, AppUpdatePreferencesHelper.getLatestApkUrl());
                Intent intent = new Intent(mContext, ApkDownloadService.class);
                intent.putExtra(ApkDownloadService.ARG_APK_URL, apkUrl);
                mContext.startService(intent);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_IS_APP_NEED_FORCE_UPDATE, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                cmd.setResult(JSInterface.PARAM_NATIVE_FORCE_UPDATE, AppUpdatePreferencesHelper.isAppNeedForceUpdate());
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SET_UNREAD_PRIVATE_MESSAGE_COUNT, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                onRequest(cmd);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_GET_UNIQUE_DEVICE_ID, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                cmd.setResult(JSInterface.PARAM_NATIVE_DEVICE_ID, TelephonyUtils.getIMEI(mContext));
            }
        });
        registerCommand(JSInterface.REQUEST_JS_SHOW_KEYBOARD, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                InputMethodManager mgr = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
                // only will trigger it if no physical keyboard is open
                mgr.showSoftInput(mWebView, InputMethodManager.SHOW_IMPLICIT);
            }
        });
        registerCommand(JSInterface.REQUEST_JS_HIDE_KEYBOARD, new JSBridge.Function() {
            @Override
            public void onExecute(Command cmd) {
                InputMethodManager mgr = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
                mgr.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
            }
        });
    }

    private Navigator getNavigator() {
        return NfsApplication.getApplication().getNavigator();
    }

    private void executeShareAction(JSBridge.Command command, BaseShareAction shareAction) {
        shareAction.setCommand(command);
        shareAction.share(mContext, ShareHolder.createShareHolderFromJson(command.getParams()));
    }

    private void onRequest(JSBridge.Command cmd) {
        String request = cmd.getName();
        JSInterface.WebActionListener listener = mListenerMap.get(request);
        if (listener != null) {
            listener.onRequest(cmd);
        }
    }

}
